package com.wfm.saver;

import cn.hutool.core.io.FileUtil;
import com.wfm.filter.BloomFilter;
import com.wfm.filter.GuavaBloomFilter;
import com.wfm.generator.Base62Generator;
import com.wfm.generator.UrlGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Optional;

import static com.wfm.constants.Constants.BASE_DIR;

@Component
@Slf4j
public class LocalFileSaver implements Saver{

    private static final int EVERY = 1000000;

    private UrlGenerator generator;

    private BloomFilter bloomFilter;

    LocalFileSaver(){
        generator = new Base62Generator();
        bloomFilter = new GuavaBloomFilter();
    }

    public void save() {
        // 生成短链到SB
        StringBuilder stringBuilder = new StringBuilder(6 * EVERY);
        int counter = appendStringBuild(stringBuilder);
        if(counter==0){
            throw new RuntimeException("生成url失败，本批次无法生成不重复的url");
        }

        // 创建文件夹
        log.info("开始写入文件");
        boolean exist = FileUtil.exist(BASE_DIR);
        if (!exist) {
            log.info("创建指定文件夹：" + BASE_DIR);
            boolean ok = FileUtil.mkdirsSafely(new File(BASE_DIR), 2, 1000);
            if (!ok) {
                log.info("创建文件夹失败");
                System.exit(1);
            }
            log.info("创建文件夹成功");
        }

        // 创建文件，并将sb写文件
        Optional<String> max = FileUtil.listFileNames(BASE_DIR).stream().max(String::compareTo);
        String data = stringBuilder.toString();
        if (max.isPresent()) {
            String s = max.get();
            long maxSize = Long.parseLong(s);
            long thisSize = maxSize + counter;
            log.info("preSize{}+counter{}=thisSize{}",maxSize,counter,thisSize);
            FileUtil.writeString(data, BASE_DIR + thisSize, "utf-8");
        } else {
            FileUtil.writeString(data, BASE_DIR + counter, "utf-8");
        }
    }

    int appendStringBuild(StringBuilder stringBuilder){
        int counter = 0;
        for (int i = 0; i < EVERY; i++) {
            String generate = generator.generate();
            boolean contains = bloomFilter.filter(generate);
            if (!contains) {
                counter++;
            } else {
                // retry three times
                for (int j = 0; j < 3; j++) {
                    generate = generator.generate();
                    contains = bloomFilter.filter(generate);
                    if (!contains) {
                        counter++;
                        break;
                    }
                    log.debug("布隆过滤器重试{}次，还未成功，直接跳过",j);
                }
            }
            stringBuilder.append(generate);
        }
        log.info("本批次共生成{}个短url",counter);
        return counter;
    }

}
